package view.Windows;

import java.sql.Date;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.graphics.FontData;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Group;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Monitor;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;

import view.Tabs.HomePageGUI;

import commons.Entities.User;
import commons.Exceptions.userAlreadyExistsException;
import commons.Exceptions.userWithNoNameException;
import commons.Exceptions.userWithNoPasswordException;
import commons.Exceptions.wrongRePasswordException;

import controller.ControllerFunctions;

public final class RegisterGUI {

	private static final Log logger = LogFactory.getLog(RegisterGUI.class);
	final public Shell shlMain;
	protected Color cBackgroundColor;
	protected Font fHeadFont;
	protected Combo cmbYears;
	protected Combo cmbMonths;
	protected Combo cmbDays;

	public RegisterGUI(final Display mainDisp) {
		// main display for the login page
		shlMain = new Shell(mainDisp, SWT.SHELL_TRIM & ~SWT.RESIZE & ~SWT.MAX);
		shlMain.setBounds(10, 10, 550, 700);

		// locate the shell in the center of the display
		Monitor primary = mainDisp.getPrimaryMonitor();
		Rectangle bounds = primary.getBounds();
		Rectangle rect = shlMain.getBounds();
		int x = bounds.x + (bounds.width - rect.width) / 2;
		int y = bounds.y + (bounds.height - rect.height) / 2;
		shlMain.setLocation(x, y);

		// main definitions
		shlMain.setText("LegenDate - Register");
		Image icon = new Image(mainDisp, getClass().getClassLoader().getResourceAsStream("view/Assets/LegenDate.png"));
		shlMain.setImage(icon);
		final Color clrWhite = new Color(mainDisp, 255, 255, 255);
		Image iBG = new Image(mainDisp, getClass().getClassLoader().getResourceAsStream("view/Assets/LegenDateBG2.jpg"));
		shlMain.setBackgroundMode(SWT.INHERIT_DEFAULT);
		shlMain.setBackgroundImage(iBG);

		// register group
		Group grRegister = new Group(shlMain, 0);
		grRegister.setBounds(50, 50, 450, 500);
		Label lblRegister = new Label(shlMain, 0);
		lblRegister.setForeground(clrWhite);
		lblRegister.setText("Register");
		lblRegister.setBounds(60, 50, 60, 30);
		lblRegister.moveAbove(grRegister);
		lblRegister.setAlignment(SWT.CENTER);

		// user name
		Label lblUser = new Label(grRegister, 0);
		lblUser.setText("UserName: ");
		lblUser.setBounds(30, 50, 70, 20);
		lblUser.setForeground(clrWhite);

		final Text txUser = new Text(grRegister, SWT.BORDER);
		txUser.setBounds(170, 50, 230, 20);

		// password
		Label lblPassword = new Label(grRegister, 0);
		lblPassword.setText("Password: ");
		lblPassword.setBounds(30, 80, 70, 20);
		lblPassword.setForeground(clrWhite);

		final Text txPassword = new Text(grRegister, SWT.BORDER | SWT.PASSWORD);
		txPassword.setBounds(170, 80, 230, 20);

		// Reenter password
		Label lblRePassword = new Label(grRegister, 0);
		lblRePassword.setText("Re-enter Password: ");
		lblRePassword.setBounds(30, 110, 130, 20);
		lblRePassword.setForeground(clrWhite);

		final Text txRePassword = new Text(grRegister, SWT.BORDER | SWT.PASSWORD);
		txRePassword.setBounds(170, 110, 230, 20);

		// first name
		Label lblFirstName = new Label(grRegister, 0);
		lblFirstName.setText("First Name: ");
		lblFirstName.setBounds(30, 140, 70, 20);
		lblFirstName.setForeground(clrWhite);

		final Text txFirstName = new Text(grRegister, SWT.BORDER);
		txFirstName.setBounds(170, 140, 230, 20);

		// last name
		Label lblLastName = new Label(grRegister, 0);
		lblLastName.setText("Last Name: ");
		lblLastName.setBounds(30, 170, 70, 20);
		lblLastName.setForeground(clrWhite);

		final Text txLastName = new Text(grRegister, SWT.BORDER);
		txLastName.setBounds(170, 170, 230, 20);

		// Email
		Label lblEmail = new Label(grRegister, 0);
		lblEmail.setText("Email: ");
		lblEmail.setBounds(30, 200, 70, 20);
		lblEmail.setForeground(clrWhite);

		final Text txEmail = new Text(grRegister, SWT.BORDER);
		txEmail.setBounds(170, 200, 230, 20);

		// sex
		Label lblSex = new Label(grRegister, 0);
		lblSex.setText("Sex: ");
		lblSex.setBounds(30, 230, 70, 20);
		lblSex.setForeground(clrWhite);

		final Button rdbSexMale = new Button(grRegister, SWT.RADIO);
		rdbSexMale.setBounds(170, 230, 60, 20);
		Label lblSexMale = new Label(grRegister, 0);
		lblSexMale.setForeground(clrWhite);
		lblSexMale.setText("Male");
		lblSexMale.setBounds(192, 230, 45, 30);
		lblSexMale.moveAbove(rdbSexMale);

		Button rdbSexFemale = new Button(grRegister, SWT.RADIO);
		rdbSexFemale.setBounds(240, 230, 90, 20);
		Label lblSexFemale = new Label(grRegister, 0);
		lblSexFemale.setForeground(clrWhite);
		lblSexFemale.setText("Female");
		lblSexFemale.setBounds(262, 230, 85, 30);
		lblSexFemale.moveAbove(rdbSexFemale);

		// Date of birth
		Label lblDateOfBirth = new Label(grRegister, 0);
		lblDateOfBirth.setText("Date of Birth: ");
		lblDateOfBirth.setBounds(30, 260, 100, 20);
		lblDateOfBirth.setForeground(clrWhite);

		String[] years = new String[112];
		for (int i = 1900, j = 0; i < 2012; j++, i++) {
			years[j] = String.valueOf(i);
		}

		String[] months = new String[12];
		for (int i = 1, j = 0; i < 13; j++, i++) {
			months[j] = String.valueOf(i);
		}

		String[] days = new String[31];
		for (int i = 1, j = 0; i < 32; j++, i++) {
			days[j] = String.valueOf(i);
		}

		cmbYears = new Combo(grRegister, 0);
		cmbYears.setItems(years);
		cmbYears.setBounds(170, 260, 70, 20);
		cmbYears.select(0);
		cmbMonths = new Combo(grRegister, 0);
		cmbMonths.setItems(months);
		cmbMonths.setBounds(245, 260, 50, 20);
		cmbMonths.select(0);
		cmbDays = new Combo(grRegister, 0);
		cmbDays.setItems(days);
		cmbDays.setBounds(300, 260, 50, 20);
		cmbDays.select(0);

		cmbYears.addSelectionListener(new SelectionAdapter() {

			// when changing the year, change the number of days in the month
			@Override
			public void widgetSelected(SelectionEvent arg0) {
				int limit = 31;
				switch (cmbMonths.getSelectionIndex() + 1) {
					case 4:
					case 6:
					case 9:
					case 11:
						limit = 30;
						break;
					case 2:
						if ((cmbYears.getSelectionIndex() + 1900) % 4 == 0)
							limit = 29;
						if ((cmbYears.getSelectionIndex() + 1900) % 100 == 0)
							limit = 28;
						if ((cmbYears.getSelectionIndex() + 1900) % 400 == 0)
							limit = 29;
						break;
					default:
						limit = 31;
						break;
				}

				String[] days = new String[limit];
				for (int i = 1, j = 0; i < limit + 1; j++, i++) {
					days[j] = String.valueOf(i);
				}

				cmbDays.setItems(days);
				cmbDays.select(0);
			}
		});

		cmbMonths.addSelectionListener(new SelectionAdapter() {

			// when changing the month, change the number of days in the month
			@Override
			public void widgetSelected(SelectionEvent arg0) {
				int limit = 31;
				switch (cmbMonths.getSelectionIndex() + 1) {
					case 4:
					case 6:
					case 9:
					case 11:
						limit = 30;
						break;
					case 2:
						if ((cmbYears.getSelectionIndex() + 1900) % 4 == 0)
							limit = 29;
						if ((cmbYears.getSelectionIndex() + 1900) % 100 == 0)
							limit = 28;
						if ((cmbYears.getSelectionIndex() + 1900) % 400 == 0)
							limit = 29;
						break;
					default:
						limit = 31;
						break;
				}

				String[] days = new String[limit];
				for (int i = 1, j = 0; i < limit + 1; j++, i++) {
					days[j] = String.valueOf(i);
				}

				cmbDays.setItems(days);
				cmbDays.select(0);

			}
		});

		FontData fontData = new FontData("Ariel", 10, SWT.BOLD);
		setHeadFont(new Font(mainDisp, fontData));

		// interested in
		Label lblInterestedIn = new Label(grRegister, 0);
		lblInterestedIn.setText("Interested In: ");
		lblInterestedIn.setBounds(30, 290, 70, 20);
		lblInterestedIn.setForeground(clrWhite);

		final Button rdbInterestedInMale = new Button(grRegister, SWT.CHECK);
		rdbInterestedInMale.setBounds(170, 290, 60, 20);
		Label lblIntInMale = new Label(grRegister, 0);
		lblIntInMale.setForeground(clrWhite);
		lblIntInMale.setText("Male");
		lblIntInMale.setBounds(192, 290, 45, 30);
		lblIntInMale.moveAbove(rdbInterestedInMale);

		final Button rdbInterestedInFemale = new Button(grRegister, SWT.CHECK);
		rdbInterestedInFemale.setBounds(240, 290, 90, 20);
		Label lblIntInFemale = new Label(grRegister, 0);
		lblIntInFemale.setForeground(clrWhite);
		lblIntInFemale.setText("Female");
		lblIntInFemale.setBounds(262, 290, 85, 30);
		lblIntInFemale.moveAbove(rdbInterestedInFemale);

		// register button
		Button btnRegister = new Button(grRegister, SWT.NONE);
		btnRegister.setFont(getHeadFont());
		btnRegister.setText("Register");
		btnRegister.setBounds(125, 400, 200, 50);
		btnRegister.addSelectionListener(new SelectionAdapter() {

			@Override
			public void widgetSelected(SelectionEvent e) {

				String in = "Don't care!";
				if (rdbInterestedInMale.getSelection()) {
					if (rdbInterestedInFemale.getSelection())
						in = "Male & Female";
					else
						in = "Male";
				} else if (rdbInterestedInFemale.getSelection())
					in = "Female";

				User user = new User();
				user.setFirstName(txFirstName.getText());
				user.setLastName(txLastName.getText());
				user.setEmail(txEmail.getText());
				user.setPassword(txPassword.getText());
				user.setUserName(txUser.getText());
				String m = (cmbMonths.getSelectionIndex() + 1) < 10 ? "0" : "";
				String d = (cmbDays.getSelectionIndex() + 1) < 10 ? "0" : "";
				user.setDateOfBirth(Date.valueOf((cmbYears.getSelectionIndex() + 1900) + "-" + m + (cmbMonths.getSelectionIndex() + 1) + "-" + d + (cmbDays.getSelectionIndex() + 1)));
				user.setGender(rdbSexMale.getSelection() ? "Male" : "Female");
				user.setIntrestedIn(in);
				try {
					ControllerFunctions.get().saveOrUpdateUser(user, txRePassword.getText(), true);
				} catch (userWithNoNameException e1) {
					logger.info(e1);
					ErrorMessageGUI errorMsg = new ErrorMessageGUI(mainDisp, e1.toString());
					errorMsg.showGUI(mainDisp);
					return;
				} catch (userWithNoPasswordException e1) {
					logger.info(e1);
					ErrorMessageGUI errorMsg = new ErrorMessageGUI(mainDisp, e1.toString());
					errorMsg.showGUI(mainDisp);
					return;
				} catch (userAlreadyExistsException e1) {
					logger.info(e1);
					ErrorMessageGUI errorMsg = new ErrorMessageGUI(mainDisp, e1.toString());
					errorMsg.showGUI(mainDisp);
					return;
				} catch (wrongRePasswordException e1) {
					logger.info(e1);
					ErrorMessageGUI errorMsg = new ErrorMessageGUI(mainDisp, e1.toString());
					errorMsg.showGUI(mainDisp);
					return;
				}
				shlMain.close();

				HomePageGUI.get().HomePageGUIRun(mainDisp, user.getUserName());
				HomePageGUI.get().showGUI(mainDisp);
				shlMain.dispose();
			}
		});

		// logout button
		Button btnBackToLogin = new Button(shlMain, SWT.NONE);
		btnBackToLogin.setFont(getHeadFont());
		btnBackToLogin.setText("Back to Login");
		btnBackToLogin.setBounds(200, 590, 150, 30);
		btnBackToLogin.addSelectionListener(new SelectionAdapter() {

			@Override
			public void widgetSelected(SelectionEvent e) {
				shlMain.close();
				Shell newShell = new Shell(mainDisp, SWT.SHELL_TRIM & ~SWT.RESIZE);
				LoginGUI.get().LoginGUIRun(mainDisp, newShell);
				shlMain.dispose();
			}
		});

	}

	public Color getBackgroundColor() {
		return cBackgroundColor;
	}

	public void setBackgroundColor(Color cBackgroundColor) {
		this.cBackgroundColor = cBackgroundColor;
	}

	public Font getHeadFont() {
		return fHeadFont;
	}

	public void setHeadFont(Font fHeadFont) {
		this.fHeadFont = fHeadFont;
	}

	/**
	 * show the shell
	 * 
	 * @param display
	 */
	public void showGUI(Display display) {
		shlMain.open();
		// this is what's holding the shell open!!!
		while (!shlMain.isDisposed()) {
			if (!display.readAndDispatch())
				display.sleep();
		}
	}
}
